package im.composer.persistent.xstream;

import java.io.InputStream;
import java.io.OutputStream;
import java.io.Reader;
import java.io.Writer;
import java.net.URL;
import java.util.Arrays;
import java.util.List;

import im.composer.persistent.xstream.converter.BitSetConverter;
import im.composer.persistent.xstream.converter.PropertiesConverter;
import im.composer.persistent.xstream.converter.SequenceConverter;
import im.composer.persistent.xstream.converter.TrackConverter;

import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.converters.Converter;

@SuppressWarnings("unchecked")
public abstract class ConfiguredXStream {
	
	private static final List<Class<? extends Converter>> converters = Arrays.asList(PropertiesConverter.class,SequenceConverter.class,TrackConverter.class,BitSetConverter.class);
	private static XStream xstream;

	private static final XStream getInstance() {
		if (xstream == null) {
			init();
		}
		return xstream;
	}

	private static synchronized void init() {
		if(xstream!=null){
			return;
		}
		xstream = new XStream();
		xstream.setMode(XStream.ID_REFERENCES);
		for(Class<? extends Converter> clz:converters){
			try {
				xstream.registerConverter(clz.newInstance());
			} catch (InstantiationException | IllegalAccessException e) {
			}
		}
	}

	public static <T> T fromXML(InputStream input) {
		return (T) getInstance().fromXML(input);
	}

	public static <T> T fromXML(Reader reader) {
		return (T) getInstance().fromXML(reader);
	}

	public static <T> T fromXML(String xml) {
		return (T) getInstance().fromXML(xml);
	}

	public static <T> T fromXML(URL url) {
		return (T) getInstance().fromXML(url);
	}

	public static void toXML(Object obj, OutputStream out) {
		getInstance().toXML(obj, out);
	}

	public static void toXML(Object obj, Writer out) {
		getInstance().toXML(obj, out);
	}

	public static String toXML(Object obj) {
		return getInstance().toXML(obj);
	}
}
